/*********************************************************************************
 *      Copyright:  (C) 2022 Li Yanting<liyanting2@163.com>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/16/2022)
 *         Author:  Li Yanting <liyanting2@163.com>
 *      ChangeLog:  1, Release initial version on "04/16/2022 06:09:30 PM"
 *                 
 ********************************************************************************/

#include "main.h"

int main(int argc, char **argv)
{
	char           *serv_ip = NULL;
	int             serv_port;
	int             interval_time;
	char           *HOST_NUMBER;
	int             daemon_run = 0;
	int             opt;
	
	float           temper;
	long            last_time;
	long            current_time;
	char            buffer[128];
	char           *format_time = NULL;

	int             rv = -1;
	int             sockfd = -1;
	sqlite3        *sql_db;

	struct option   opt_long[] = 
	{
		{"serv_ip", required_argument, NULL, 'i'},
		{"serv_port", required_argument, NULL, 'p'},
		{"interval_time", required_argument, NULL, 't'},
		{"HOST_NUMBER", required_argument, NULL, 'n'},
		{"daemon_run", no_argument, NULL, 'b'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	while( (opt = getopt_long(argc, argv, "i:p:t:n:bh", opt_long, NULL)) != -1 )
	{
		dbg_printf("opt: %c\n", opt);
		switch(opt)
		{
			case 'i':
				serv_ip = optarg;
				break;
			case 'p':
				serv_port = atoi(optarg);
				break;
			case 't':
				interval_time = atoi(optarg);
				break;
			case 'n':
				HOST_NUMBER = optarg;
				break;
			case 'b':
				daemon_run = 1;
				break;
			case 'h':
				print_usage(argv[0]);
				return 0;
			default :
				print_usage(argv[0]);
				return 0;
		}
	}

    while( !serv_ip || !serv_port || !interval_time || !HOST_NUMBER )
    {
       print_usage(argv[0]);
       return -1;
    }

	if( (rv = logger_init("running.log", LOG_LEVEL_DEBUG)) < 0)
    {
        fprintf(stderr, "initial logger system failure\n");
        return -2;
    }

	signal(SIGINT, program_stop);
	signal(SIGTERM, program_stop);

	if( daemon_run )
	{
		dbg_printf("The program will run in the background.\n");
		log_info("The program running in the background.\n");
		daemon(0, 0);
	}

	open_database(&sql_db);
	create_statement(sql_db, HOST_NUMBER);

	if( (sockfd = socket_connect_client(serv_ip, serv_port)) < 0 )
	{
		log_error("socket_connect_client failure.\n");
	}
	log_error("socket_connect_client successfully.\n");
	dbg_printf("socket_connect_client successfully.\n");

	while( !g_prog_stop )
	{
		get_temperature(&temper);
		dbg_printf("got temper: %f.\n", temper);
	
		get_time(&last_time);
		format_time = get_format_time(last_time);
		sprintf(buffer, "%s | %s | %f \n", HOST_NUMBER, format_time, temper);
		dbg_printf("got data: %s\n", buffer);
		dbg_printf("\n");

		while( !g_prog_stop )
		{
			sleep(2);
			if( get_socket_state(sockfd) < 0 )
			{
				dbg_printf("socket disconnect.\n");
				if( sockfd > 0 )
				{
					close(sockfd);
					dbg_printf("close sockfd[%d].\n", sockfd);
				}

				sockfd = socket_connect_client(serv_ip, serv_port);
				dbg_printf("\n");
			}

			get_time(&current_time);
			dbg_printf("get current time: %ld\n", current_time);
			dbg_printf("\n");

			if( current_time - last_time < interval_time )
			{
				dbg_printf("time not arrived.\n");

				if( (rv = sql_check(sql_db, HOST_NUMBER)) < 0 )
				{
					dbg_printf("sql no data.\n");
					dbg_printf("\n");
					continue;
				}
				dbg_printf("sql have data.\n");

				if( (rv = sql_write_to_server(sql_db, sockfd, HOST_NUMBER)) < 0 )
				{
					dbg_printf("sql write to server failure.\n");
					dbg_printf("\n");
					continue;
				}
				dbg_printf("sql write to server successfully.\n");

				sql_delete(sql_db, HOST_NUMBER);
				dbg_printf("\n");
				continue;
			}
			else
			{
				dbg_printf("time arrived.\n");

				if( get_socket_state(sockfd) < 0 )
				{
					sql_insert(sql_db, HOST_NUMBER, format_time, temper);
					break;
				}

				if( (rv = write(sockfd, buffer, strlen(buffer))) < 0 )
				{
					dbg_printf("write data to server failure: %s.\n", strerror(errno));
					sql_insert(sql_db, HOST_NUMBER, format_time, temper);
				}
				else
					dbg_printf("write data(%s) to server successfully.\n", buffer);
	
				break;
			}
		}
		last_time = current_time;
		dbg_printf("\n\n\n\n\n");
	}
	close(sockfd);
}

void program_stop(int sigsum)
{
	g_prog_stop = 1;
}


